Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>AI Logistics Coordinator — OpenEnv Hackathon 2026</title> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700;900&family=JetBrains+Mono:wght@400;600&display=swap'); | |
| :root { | |
| --bg: #0d1117; --surface: #161b22; --border: #30363d; | |
| --text: #e6edf3; --muted: #8b949e; --green: #3fb950; | |
| --red: #f85149; --blue: #58a6ff; --orange: #f0883e; | |
| --accent: #238636; | |
| } | |
| * { margin: 0; padding: 0; box-sizing: border-box; } | |
| html, body { height: 100%; background: var(--bg); font-family: 'Inter', sans-serif; color: var(--text); overflow: hidden; } | |
| .deck { width: 100%; height: 100vh; position: relative; } | |
| .slide { | |
| display: none; position: absolute; inset: 0; | |
| flex-direction: column; justify-content: center; align-items: center; | |
| padding: 60px 80px; text-align: center; | |
| background: radial-gradient(ellipse at 50% 0%, #161b22 0%, #0d1117 70%); | |
| } | |
| .slide.active { display: flex; } | |
| h1 { font-size: 2.8rem; font-weight: 900; line-height: 1.15; } | |
| h2 { font-size: 2rem; font-weight: 700; margin-bottom: 1rem; } | |
| h3 { font-size: 1.3rem; font-weight: 600; color: var(--blue); margin-bottom: 0.5rem; } | |
| p { font-size: 1.1rem; line-height: 1.7; color: var(--muted); max-width: 800px; } | |
| .tag { | |
| display: inline-block; padding: 4px 12px; border-radius: 20px; | |
| font-size: 0.8rem; font-weight: 600; margin: 4px; | |
| background: rgba(88,166,255,0.1); border: 1px solid var(--blue); color: var(--blue); | |
| } | |
| .tag.green { background: rgba(63,185,80,0.1); border-color: var(--green); color: var(--green); } | |
| .tag.orange { background: rgba(240,136,62,0.1); border-color: var(--orange); color: var(--orange); } | |
| .highlight { | |
| font-size: 4rem; font-weight: 900; | |
| background: linear-gradient(135deg, var(--green), var(--blue)); | |
| -webkit-background-clip: text; -webkit-text-fill-color: transparent; | |
| } | |
| .sub { font-size: 1rem; color: var(--muted); margin-top: 0.25rem; } | |
| .grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; width: 100%; max-width: 1000px; margin-top: 1.5rem; } | |
| .grid-2 { grid-template-columns: repeat(2, 1fr); } | |
| .grid-4 { grid-template-columns: repeat(4, 1fr); } | |
| .card { | |
| background: var(--surface); border: 1px solid var(--border); border-radius: 12px; | |
| padding: 20px; text-align: left; | |
| } | |
| .card .icon { font-size: 1.8rem; margin-bottom: 8px; } | |
| .card h4 { font-size: 1rem; font-weight: 600; margin-bottom: 6px; } | |
| .card p { font-size: 0.85rem; color: var(--muted); max-width: none; } | |
| .metric { display: flex; flex-direction: column; align-items: center; padding: 24px 12px; } | |
| .metric .num { font-size: 2.4rem; font-weight: 900; color: var(--green); } | |
| .metric .label { font-size: 0.8rem; color: var(--muted); text-align: center; margin-top: 4px; } | |
| .badge { | |
| display: inline-block; padding: 6px 16px; border-radius: 6px; | |
| background: var(--accent); color: #fff; font-weight: 700; | |
| font-size: 0.9rem; margin: 6px; | |
| } | |
| .badge.red { background: #6e1d1a; } | |
| .badge.blue { background: #0c2d6b; } | |
| table { width: 100%; border-collapse: collapse; font-size: 0.9rem; margin-top: 1rem; } | |
| th { background: var(--surface); color: var(--blue); padding: 10px 14px; text-align: left; border-bottom: 1px solid var(--border); } | |
| td { padding: 10px 14px; border-bottom: 1px solid var(--border); color: var(--muted); } | |
| td strong { color: var(--text); } | |
| .reward-bar { display: flex; align-items: center; gap: 12px; margin: 6px 0; } | |
| .reward-bar .label { width: 160px; text-align: right; font-size: 0.85rem; color: var(--muted); flex-shrink: 0; } | |
| .reward-bar .bar-wrap { flex: 1; background: var(--border); border-radius: 4px; height: 16px; } | |
| .reward-bar .bar { height: 16px; border-radius: 4px; transition: width 0.6s ease; } | |
| .reward-bar .val { font-size: 0.85rem; font-weight: 700; flex-shrink: 0; width: 55px; } | |
| .code { | |
| font-family: 'JetBrains Mono', monospace; font-size: 0.85rem; | |
| background: var(--surface); border: 1px solid var(--border); | |
| border-radius: 8px; padding: 16px; text-align: left; | |
| color: var(--green); width: 100%; max-width: 700px; margin-top: 1rem; | |
| } | |
| .code .comment { color: var(--muted); } | |
| .penalty { color: var(--red); font-weight: 700; } | |
| .bonus { color: var(--green); font-weight: 700; } | |
| /* Nav */ | |
| .nav { | |
| position: fixed; bottom: 30px; left: 50%; transform: translateX(-50%); | |
| display: flex; gap: 12px; align-items: center; z-index: 100; | |
| background: rgba(22,27,34,0.9); border: 1px solid var(--border); | |
| border-radius: 40px; padding: 10px 20px; backdrop-filter: blur(10px); | |
| } | |
| .nav button { | |
| background: none; border: none; color: var(--muted); cursor: pointer; | |
| font-size: 1.1rem; padding: 4px 10px; border-radius: 20px; transition: all 0.2s; | |
| } | |
| .nav button:hover { background: var(--surface); color: var(--text); } | |
| .nav .counter { color: var(--muted); font-size: 0.85rem; min-width: 50px; text-align: center; } | |
| .slide-num { | |
| position: fixed; top: 20px; right: 30px; | |
| font-size: 0.8rem; color: var(--border); | |
| } | |
| .logo { font-size: 3.5rem; margin-bottom: 16px; } | |
| .subtitle { font-size: 1.2rem; color: var(--muted); margin-top: 12px; } | |
| .spacer { margin-top: 1.5rem; } | |
| .link { color: var(--blue); text-decoration: none; font-size: 0.85rem; } | |
| .link:hover { text-decoration: underline; } | |
| /* Animate in */ | |
| .slide.active .card, .slide.active .metric { | |
| animation: fadeUp 0.4s ease both; | |
| } | |
| .slide.active .card:nth-child(2) { animation-delay: 0.08s; } | |
| .slide.active .card:nth-child(3) { animation-delay: 0.16s; } | |
| .slide.active .card:nth-child(4) { animation-delay: 0.24s; } | |
| @keyframes fadeUp { | |
| from { opacity: 0; transform: translateY(20px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .arrow { font-size: 1.4rem; color: var(--border); margin: 0 8px; } | |
| .flow { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; margin-top: 1.5rem; gap: 4px; } | |
| .flow-step { | |
| background: var(--surface); border: 1px solid var(--border); border-radius: 8px; | |
| padding: 10px 18px; font-size: 0.9rem; font-weight: 600; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="deck"> | |
| <!-- SLIDE 1: TITLE --> | |
| <div class="slide active"> | |
| <div class="logo">🚛</div> | |
| <h1>AI Logistics Coordinator</h1> | |
| <p class="subtitle">Teaching an LLM to manage freight crises using GRPO reinforcement learning</p> | |
| <div class="spacer"></div> | |
| <div> | |
| <span class="tag green">OpenEnv Compatible</span> | |
| <span class="tag">GRPO + TRL + Unsloth</span> | |
| <span class="tag orange">Qwen2.5-1.5B</span> | |
| <span class="tag">Meta PyTorch Hackathon 2026</span> | |
| </div> | |
| <div class="spacer"></div> | |
| <p> | |
| <a class="link" href="https://huggingface.co/spaces/Leavin1611/logistics-hackathon-env">🤗 Live Space</a> · | |
| <a class="link" href="https://huggingface.co/Leavin1611/logistics-hackathon-model">🧠 Trained Model</a> · | |
| <a class="link" href="https://colab.research.google.com/drive/1fRfheRZd1tffKjXKZkW72ffl9JPxDpL8">📓 Colab Notebook</a> | |
| </p> | |
| </div> | |
| <!-- SLIDE 2: THE PROBLEM --> | |
| <div class="slide"> | |
| <h2>It's 3 AM. A port strike just shut down Mumbai.</h2> | |
| <p>COVID vaccines are stranded on Route R1. Election ballots are stuck at Delhi. ₹1.8 crore of server hardware is 7 hours late. A human dispatcher needs 30 minutes to triage this. We built an agent that does it in seconds.</p> | |
| <div class="grid grid-2" style="margin-top: 2rem; max-width: 800px;"> | |
| <div class="card"> | |
| <div class="icon">❌</div> | |
| <h4>Current Systems</h4> | |
| <p>Rule-based optimizers. Great at routine scheduling. Fail completely when disruptions cascade. Cannot reason, cannot prioritize, cannot communicate.</p> | |
| </div> | |
| <div class="card"> | |
| <div class="icon">✅</div> | |
| <h4>Our Agent</h4> | |
| <p>Reasons about network congestion, triages by urgency, reroutes strategically, and sends empathetic messages to customers — all in a single turn.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- SLIDE 3: ENVIRONMENT --> | |
| <div class="slide"> | |
| <h2>🌍 The Environment</h2> | |
| <p>A real-time Indian freight network crisis simulator. The agent plays a centralized logistics coordinator managing cascading disruptions across JNPT, Delhi, and Mundra.</p> | |
| <div class="grid" style="margin-top: 1.5rem;"> | |
| <div class="card"> | |
| <div class="icon">👁️</div> | |
| <h4>What Agent Sees</h4> | |
| <p>Shipment states, route congestion (0–100%), active disruptions, SLA time remaining, carrier availability</p> | |
| </div> | |
| <div class="card"> | |
| <div class="icon">🎮</div> | |
| <h4>What Agent Does</h4> | |
| <p><code>get_network_status</code> · <code>reroute_shipment</code> · <code>set_priority</code> · <code>communicate_eta</code> · <code>end_turn</code></p> | |
| </div> | |
| <div class="card"> | |
| <div class="icon">🏆</div> | |
| <h4>Three Task Tiers</h4> | |
| <p>EASY (2 ships, 1 disruption) → MEDIUM (4 ships, 3 disruptions) → HARD (7 ships, 4 failures)</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- SLIDE 4: WHAT MAKES IT NOVEL --> | |
| <div class="slide"> | |
| <h2>🔬 What Makes This Novel</h2> | |
| <div class="grid grid-2" style="max-width: 900px; margin-top: 1.5rem;"> | |
| <div class="card"> | |
| <div class="icon">🌐</div> | |
| <h4>Multi-Agent Pressure</h4> | |
| <p>Background agents compete for the same limited route capacity every turn. The agent must model the network — not just react to individual shipments.</p> | |
| </div> | |
| <div class="card"> | |
| <div class="icon">⏳</div> | |
| <h4>Long-Horizon Planning</h4> | |
| <p>5–7 turn episodes. Early decisions cascade. Saving the pharmaceutical shipment on turn 1 changes which routes are available on turn 4.</p> | |
| </div> | |
| <div class="card"> | |
| <div class="icon">🧠</div> | |
| <h4>World Modeling Required</h4> | |
| <p>Partially observable. The agent must call tools to see the network. It cannot assume anything — it must build its own world model each turn.</p> | |
| </div> | |
| <div class="card"> | |
| <div class="icon">💬</div> | |
| <h4>NLP-Graded Communication</h4> | |
| <p>ETA messages are scored for empathy, specificity, and cause explanation. A unique test of "soft skills" that no other logistics env tests.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- SLIDE 5: REWARD DESIGN --> | |
| <div class="slide"> | |
| <h2>🎯 Anti-Gameable Reward Design</h2> | |
| <p>Three independent reward functions. Each has explicit negative penalties to prevent exploitation.</p> | |
| <div class="grid" style="margin-top: 1.5rem;"> | |
| <div class="card"> | |
| <h4>🏗️ Structure Reward</h4> | |
| <p><span class="bonus">+0.4</span> Start with status check<br><span class="bonus">+0.3</span> End with end_turn<br><span class="penalty">-0.5</span> Duplicate end_turn (spam)<br><span class="penalty">-0.3</span> Repeated status calls</p> | |
| </div> | |
| <div class="card"> | |
| <h4>🛣️ Routing Reward</h4> | |
| <p><span class="bonus">+0.9</span> Clear route chosen<br><span class="bonus">+0.5</span> All ships rerouted<br><span class="penalty">-0.6</span> Congested route<br><span class="penalty">-0.8</span> Empty route ID (loophole)</p> | |
| </div> | |
| <div class="card"> | |
| <h4>📢 Communication Reward</h4> | |
| <p><span class="bonus">+0.4</span> Message to delayed ship<br><span class="bonus">+0.2</span> Empathy keywords<br><span class="bonus">+0.1</span> Specific ETA given<br><span class="penalty">-0.3</span> Duplicate message (spam)</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- SLIDE 6: TRAINING PIPELINE --> | |
| <div class="slide"> | |
| <h2>🏋️ 4-Phase GRPO Curriculum</h2> | |
| <p>Group Relative Policy Optimization — the same algorithm behind DeepSeek-R1 — on a free Colab T4 GPU.</p> | |
| <div class="flow"> | |
| <div class="flow-step">🟢 Phase 1<br><small>TASK-EASY<br>lr=2e-5</small></div> | |
| <span class="arrow">→</span> | |
| <div class="flow-step">🟡 Phase 2<br><small>TASK-MEDIUM<br>lr=1e-5</small></div> | |
| <span class="arrow">→</span> | |
| <div class="flow-step">🔥 Phase 3<br><small>Mixed Hardening<br>6 rollouts</small></div> | |
| <span class="arrow">→</span> | |
| <div class="flow-step">🚨 Phase 4<br><small>Correction Cycle<br>Loophole patch</small></div> | |
| </div> | |
| <div class="grid grid-4" style="margin-top: 1.5rem; max-width: 900px;"> | |
| <div class="metric"><div class="num">1.5B</div><div class="label">Model size<br>(Qwen2.5)</div></div> | |
| <div class="metric"><div class="num">4-bit</div><div class="label">QLoRA quantization<br>(Unsloth)</div></div> | |
| <div class="metric"><div class="num">150+</div><div class="label">Training<br>episodes</div></div> | |
| <div class="metric"><div class="num">Free</div><div class="label">Colab T4<br>GPU</div></div> | |
| </div> | |
| </div> | |
| <!-- SLIDE 7: RESULTS --> | |
| <div class="slide"> | |
| <h2>📈 Results: Observable Evidence</h2> | |
| <div class="highlight">+327%</div> | |
| <div class="sub">Live environment reward improvement (0.18 baseline → 0.7683 trained)</div> | |
| <div style="width: 100%; max-width: 700px; margin-top: 2rem;"> | |
| <div class="reward-bar"> | |
| <div class="label">Untrained Baseline</div> | |
| <div class="bar-wrap"><div class="bar" style="width:23.4%;background:var(--red)"></div></div> | |
| <div class="val" style="color:var(--red)">0.18</div> | |
| </div> | |
| <div class="reward-bar"> | |
| <div class="label">After Phase 1 (Easy)</div> | |
| <div class="bar-wrap"><div class="bar" style="width:54.7%;background:var(--muted)"></div></div> | |
| <div class="val" style="color:var(--muted)">0.42</div> | |
| </div> | |
| <div class="reward-bar"> | |
| <div class="label">After Phase 2 (Medium)</div> | |
| <div class="bar-wrap"><div class="bar" style="width:79.4%;background:var(--orange)"></div></div> | |
| <div class="val" style="color:var(--orange)">0.61</div> | |
| </div> | |
| <div class="reward-bar"> | |
| <div class="label">Final (lora-final-perfect)</div> | |
| <div class="bar-wrap"><div class="bar" style="width:100%;background:var(--green)"></div></div> | |
| <div class="val" style="color:var(--green)">0.7683</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- SLIDE 8: WHAT THE AGENT LEARNED --> | |
| <div class="slide"> | |
| <h2>🤖 What the Agent Actually Learned</h2> | |
| <div class="grid grid-2" style="max-width: 900px; margin-top: 1.5rem;"> | |
| <div class="card"> | |
| <div class="icon">🔍</div> | |
| <h4>World Modeling</h4> | |
| <p>Always calls <code>get_network_status</code> first. Builds a mental model of the entire network before acting — not guessing.</p> | |
| </div> | |
| <div class="card"> | |
| <div class="icon">🛣️</div> | |
| <h4>Strategic Routing</h4> | |
| <p>Checks route congestion before rerouting. Avoids the -0.6 penalty for choosing overloaded routes. 3+ reroutes per episode vs 1 before training.</p> | |
| </div> | |
| <div class="card"> | |
| <div class="icon">💬</div> | |
| <h4>Empathetic Communication</h4> | |
| <p>Sends well-formed apologies with specific ETAs and causes. "We sincerely apologise — your shipment will arrive by 6PM due to port congestion."</p> | |
| </div> | |
| <div class="card"> | |
| <div class="icon">🚫</div> | |
| <h4>Stopped Hacking</h4> | |
| <p>Stopped spamming messages and empty routes after Phase 4 correction. Learned that strategic play earns more reward than loopholes.</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- SLIDE 9: LINKS & RESOURCES --> | |
| <div class="slide"> | |
| <h2>🔗 All Submission Links</h2> | |
| <table style="max-width: 700px; margin-top: 1rem;"> | |
| <tr><th>Resource</th><th>Link</th></tr> | |
| <tr><td>🤗 Live HF Space</td><td><a class="link" href="https://huggingface.co/spaces/Leavin1611/logistics-hackathon-env">spaces/Leavin1611/logistics-hackathon-env</a></td></tr> | |
| <tr><td>🧠 Trained Model</td><td><a class="link" href="https://huggingface.co/Leavin1611/logistics-hackathon-model">Leavin1611/logistics-hackathon-model</a></td></tr> | |
| <tr><td>📓 Training Notebook</td><td><a class="link" href="https://colab.research.google.com/drive/1fRfheRZd1tffKjXKZkW72ffl9JPxDpL8">Open in Colab</a></td></tr> | |
| <tr><td>📝 Mini-Blog</td><td><a class="link" href="https://huggingface.co/spaces/Leavin1611/logistics-hackathon-env/blob/main/HF_BLOG_POST.md">HF_BLOG_POST.md</a></td></tr> | |
| <tr><td>🏗️ Environment Code</td><td><a class="link" href="https://huggingface.co/spaces/Leavin1611/logistics-hackathon-env/blob/main/server/environment.py">server/environment.py</a></td></tr> | |
| </table> | |
| <div class="spacer"></div> | |
| <p><em>Stack: OpenEnv · FastAPI · TRL · GRPO · Unsloth · Qwen2.5-1.5B · Google Colab T4</em></p> | |
| </div> | |
| </div> | |
| <!-- Nav --> | |
| <div class="nav"> | |
| <button onclick="prev()">◀</button> | |
| <span class="counter" id="counter">1 / 9</span> | |
| <button onclick="next()">▶</button> | |
| </div> | |
| <script> | |
| let current = 0; | |
| const slides = document.querySelectorAll('.slide'); | |
| function show(n) { | |
| slides[current].classList.remove('active'); | |
| current = (n + slides.length) % slides.length; | |
| slides[current].classList.add('active'); | |
| document.getElementById('counter').textContent = `${current+1} / ${slides.length}`; | |
| } | |
| function next() { show(current + 1); } | |
| function prev() { show(current - 1); } | |
| document.addEventListener('keydown', e => { | |
| if (e.key === 'ArrowRight' || e.key === ' ') next(); | |
| if (e.key === 'ArrowLeft') prev(); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |