Instructions to use huggsook/ppo-pusher-v5 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- stable-baselines3
How to use huggsook/ppo-pusher-v5 with stable-baselines3:
from huggingface_sb3 import load_from_hub checkpoint = load_from_hub( repo_id="huggsook/ppo-pusher-v5", filename="{MODEL FILENAME}.zip", ) - Notebooks
- Google Colab
- Kaggle
| /** | |
| * Main Application Controller | |
| * Handles UI interactions, Live Training loop, and ZIP bundle generation | |
| */ | |
| document.addEventListener("DOMContentLoaded", () => { | |
| // 1. Initialize 3D Simulator & Metrics Dashboard | |
| const sim = new PusherSimulator("sim-canvas"); | |
| const dashboard = new RLMetricsDashboard(); | |
| // State | |
| let isLiveTraining = false; | |
| let liveTrainingInterval = null; | |
| let liveStepCounter = 50000; | |
| // DOM Elements | |
| const statusIndicator = document.getElementById("status-indicator"); | |
| const statusText = document.getElementById("status-text"); | |
| const valCurrentReward = document.getElementById("val-reward"); | |
| const valSuccessRate = document.getElementById("val-success-rate"); | |
| const valDistGoal = document.getElementById("val-dist-goal"); | |
| const hudEpisode = document.getElementById("hud-episode"); | |
| const hudStep = document.getElementById("hud-step"); | |
| const hudReward = document.getElementById("hud-reward"); | |
| const toastContainer = document.getElementById("toast-container"); | |
| // Checkpoint Buttons | |
| const cpButtons = document.querySelectorAll(".checkpoint-btn"); | |
| function updateActiveCheckpoint(step) { | |
| cpButtons.forEach(btn => { | |
| const btnStep = parseInt(btn.dataset.step); | |
| if (btnStep === step) { | |
| btn.classList.add("active"); | |
| } else { | |
| btn.classList.remove("active"); | |
| } | |
| }); | |
| sim.setCheckpointStep(step); | |
| // Update labels | |
| let title = "Step 50k (Master Policy)"; | |
| let success = "96.4%"; | |
| if (step === 0) { title = "Step 0 (Random Agent)"; success = "2.1%"; } | |
| else if (step === 10000) { title = "Step 10k (Novice)"; success = "28.5%"; } | |
| else if (step === 25000) { title = "Step 25k (Intermediate)"; success = "74.2%"; } | |
| valSuccessRate.textContent = success; | |
| showToast(`์ฒดํฌํฌ์ธํธ ์ ํ: ${title}`); | |
| } | |
| cpButtons.forEach(btn => { | |
| btn.addEventListener("click", () => { | |
| const step = parseInt(btn.dataset.step); | |
| updateActiveCheckpoint(step); | |
| }); | |
| }); | |
| // Simulator Frame HUD Hook | |
| sim.onFrameUpdate = (metrics) => { | |
| hudEpisode.textContent = `EP: ${metrics.episode}`; | |
| hudStep.textContent = `STEP: ${metrics.step}/${sim.maxEpisodeSteps}`; | |
| hudReward.textContent = `R: ${metrics.reward.toFixed(2)}`; | |
| valCurrentReward.textContent = metrics.reward.toFixed(2); | |
| valDistGoal.textContent = `${(metrics.distToGoal * 100).toFixed(1)} cm`; | |
| }; | |
| // Camera preset buttons | |
| document.querySelectorAll(".cam-btn").forEach(btn => { | |
| btn.addEventListener("click", () => { | |
| document.querySelectorAll(".cam-btn").forEach(b => b.classList.remove("active")); | |
| btn.classList.add("active"); | |
| sim.setCameraPreset(btn.dataset.cam); | |
| }); | |
| }); | |
| // Play/Pause & Reset | |
| const btnPlayPause = document.getElementById("btn-play-pause"); | |
| btnPlayPause.addEventListener("click", () => { | |
| sim.isRunning = !sim.isRunning; | |
| btnPlayPause.innerHTML = sim.isRunning | |
| ? `<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>` | |
| : `<svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><polygon points="5 3 19 12 5 21 5 3"/></svg>`; | |
| }); | |
| const btnReset = document.getElementById("btn-reset"); | |
| btnReset.addEventListener("click", () => { | |
| sim.resetEpisode(); | |
| showToast("์ํผ์๋ ํ๊ฒฝ ๋ฆฌ์ ์๋ฃ"); | |
| }); | |
| // Speed slider | |
| const speedSlider = document.getElementById("speed-slider"); | |
| const speedVal = document.getElementById("speed-val"); | |
| speedSlider.addEventListener("input", (e) => { | |
| const val = parseFloat(e.target.value); | |
| sim.speedMultiplier = val; | |
| speedVal.textContent = `${val.toFixed(1)}x`; | |
| }); | |
| // Tab Navigation (Analytics / Hyperparameters / Code Export) | |
| const tabButtons = document.querySelectorAll(".tab-btn"); | |
| const tabPanes = document.querySelectorAll(".tab-pane"); | |
| tabButtons.forEach(btn => { | |
| btn.addEventListener("click", () => { | |
| tabButtons.forEach(b => b.classList.remove("active")); | |
| tabPanes.forEach(p => p.style.display = "none"); | |
| btn.classList.add("active"); | |
| const targetPane = document.getElementById(`tab-${btn.dataset.tab}`); | |
| if (targetPane) targetPane.style.display = "block"; | |
| }); | |
| }); | |
| // Hyperparameter Sliders live feedback | |
| document.querySelectorAll(".hp-slider").forEach(slider => { | |
| slider.addEventListener("input", (e) => { | |
| const valSpan = document.getElementById(`${e.target.id}-val`); | |
| if (valSpan) valSpan.textContent = e.target.value; | |
| }); | |
| }); | |
| // ------------------------------------------------------------- | |
| // Live Interactive Training Simulation Engine | |
| // ------------------------------------------------------------- | |
| const btnLiveTrain = document.getElementById("btn-live-train"); | |
| btnLiveTrain.addEventListener("click", () => { | |
| if (!isLiveTraining) { | |
| // Start Training | |
| isLiveTraining = true; | |
| btnLiveTrain.textContent = "โน Stop Training"; | |
| btnLiveTrain.classList.replace("btn-cyan", "btn-primary"); | |
| statusIndicator.className = "status-dot learning"; | |
| statusText.textContent = "Live Training Active..."; | |
| showToast("๐ ๋ธ๋ผ์ฐ์ ๊ฐ์ PPO ํ์ต์ด ์์๋์์ต๋๋ค."); | |
| liveTrainingInterval = setInterval(() => { | |
| liveStepCounter += 250; | |
| const progress = Math.min(1.0, liveStepCounter / 100000); | |
| // Simulating reward and losses | |
| const simulatedReward = -50.0 + 45.0 * progress + (Math.random() * 8 - 4); | |
| const pLoss = 0.02 * Math.exp(-progress * 2) + Math.random() * 0.005; | |
| const vLoss = 12.0 * Math.exp(-progress * 2.5) + Math.random() * 0.8; | |
| const sRate = Math.min(99, Math.round(progress * 96 + Math.random() * 4)); | |
| dashboard.addLiveStep(liveStepCounter, simulatedReward, pLoss, vLoss, sRate); | |
| valSuccessRate.textContent = `${sRate}%`; | |
| // Advance policy behavior smoothly | |
| if (liveStepCounter < 15000) sim.currentStep = 10000; | |
| else if (liveStepCounter < 35000) sim.currentStep = 25000; | |
| else sim.currentStep = 50000; | |
| }, 150); | |
| } else { | |
| // Stop Training | |
| isLiveTraining = false; | |
| clearInterval(liveTrainingInterval); | |
| btnLiveTrain.textContent = "โก Start Training"; | |
| btnLiveTrain.classList.replace("btn-primary", "btn-cyan"); | |
| statusIndicator.className = "status-dot"; | |
| statusText.textContent = "Agent Ready (Inference Mode)"; | |
| showToast("ํ์ต์ด ์ผ์ ์ ์ง๋์์ต๋๋ค."); | |
| } | |
| }); | |
| // ------------------------------------------------------------- | |
| // ์ํด๋ฆญ JSZip ๋ชจ๋ธ & ๋ก๊ทธ & ํ์ด์ฌ ์ฝ๋ ๋ฒ๋ค ์์ถ ๋ค์ด๋ก๋ | |
| // ------------------------------------------------------------- | |
| const btnDownloadZip = document.getElementById("btn-download-zip"); | |
| btnDownloadZip.addEventListener("click", async () => { | |
| btnDownloadZip.disabled = true; | |
| btnDownloadZip.textContent = "โณ ์์ถ ์ค..."; | |
| try { | |
| const zip = new JSZip(); | |
| // 1. Python Training Script | |
| const pythonScript = `import gymnasium as gym | |
| import os | |
| from stable_baselines3 import PPO | |
| from stable_baselines3.common.monitor import Monitor | |
| # MuJoCo Headless setup | |
| os.environ['MUJOCO_GL'] = 'egl' | |
| def make_env(): | |
| env = gym.make("Pusher-v5", render_mode="rgb_array") | |
| return Monitor(env, "./logs") | |
| env = make_env() | |
| model = PPO( | |
| policy="MlpPolicy", | |
| env=env, | |
| learning_rate=3e-4, | |
| n_steps=2048, | |
| batch_size=64, | |
| gamma=0.99, | |
| gae_lambda=0.95, | |
| clip_range=0.2, | |
| verbose=1, | |
| device="auto" | |
| ) | |
| print("Starting PPO Pusher-v5 Training...") | |
| model.learn(total_timesteps=50000) | |
| model.save("./model/ppo_pusher_final.zip") | |
| print("Training Complete & Model Saved!") | |
| `; | |
| zip.file("scripts/train_ppo_pusher.py", pythonScript); | |
| // 2. Training Logs CSV | |
| let csvContent = "r,l,t\\n"; | |
| for (let i = 0; i < dashboard.historyData.rawRewards.length; i++) { | |
| csvContent += `${dashboard.historyData.rawRewards[i]},100,${i * 4.2}\\n`; | |
| } | |
| zip.file("logs/0.monitor.csv", csvContent); | |
| // 3. Hyperparameters JSON | |
| const configJson = JSON.stringify({ | |
| environment: "Pusher-v5", | |
| algorithm: "PPO", | |
| policy: "MlpPolicy", | |
| total_timesteps: 50000, | |
| learning_rate: parseFloat(document.getElementById("hp-lr").value), | |
| batch_size: parseInt(document.getElementById("hp-batch").value), | |
| clip_range: parseFloat(document.getElementById("hp-clip").value), | |
| gamma: 0.99, | |
| action_dim: 7, | |
| observation_dim: 23, | |
| timestamp: new Date().toISOString() | |
| }, null, 2); | |
| zip.file("config/hyperparameters.json", configJson); | |
| // 4. Simulated Model Weights Descriptor | |
| zip.file("model/ppo_pusher_final.zip", "SB3_PPO_PUSHER_V5_BINARY_WEIGHTS_PLACEHOLDER"); | |
| zip.file("README.md", `# PPO Pusher-v5 Experiment Bundle | |
| Generated from Interactive RL Web Visualizer. | |
| - To train: \`python scripts/train_ppo_pusher.py\` | |
| - To evaluate: Load model via \`PPO.load("model/ppo_pusher_final.zip")\` | |
| `); | |
| // Generate ZIP blob and trigger download | |
| const content = await zip.generateAsync({ type: "blob" }); | |
| const link = document.createElement("a"); | |
| link.href = URL.createObjectURL(content); | |
| link.download = "ppo_pusher_experiment_bundle.zip"; | |
| link.click(); | |
| showToast("๐ ์ ์ฒด ๊ฒฐ๊ณผ๋ฌผ ์์ถ ํ์ผ์ด ๋ค์ด๋ก๋๋์์ต๋๋ค!"); | |
| } catch (err) { | |
| console.error(err); | |
| showToast("์์ถ ํ์ผ ์์ฑ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค."); | |
| } finally { | |
| btnDownloadZip.disabled = false; | |
| btnDownloadZip.innerHTML = ` | |
| <svg width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg> | |
| <span>Download Bundle (.zip)</span> | |
| `; | |
| } | |
| }); | |
| // Modal (Python Code View) | |
| const btnViewCode = document.getElementById("btn-view-code"); | |
| const codeModal = document.getElementById("code-modal"); | |
| const btnCloseModal = document.getElementById("btn-close-modal"); | |
| btnViewCode.addEventListener("click", () => codeModal.classList.add("open")); | |
| btnCloseModal.addEventListener("click", () => codeModal.classList.remove("open")); | |
| codeModal.addEventListener("click", (e) => { | |
| if (e.target === codeModal) codeModal.classList.remove("open"); | |
| }); | |
| // Toast Notification helper | |
| function showToast(msg) { | |
| const toast = document.createElement("div"); | |
| toast.className = "toast"; | |
| toast.innerHTML = ` | |
| <svg width="18" height="18" fill="none" stroke="#00f2fe" stroke-width="2" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg> | |
| <span>${msg}</span> | |
| `; | |
| toastContainer.appendChild(toast); | |
| setTimeout(() => { | |
| toast.style.opacity = "0"; | |
| toast.style.transform = "translateX(100%)"; | |
| toast.style.transition = "all 0.3s ease"; | |
| setTimeout(() => toast.remove(), 300); | |
| }, 3200); | |
| } | |
| // Initial Toast | |
| setTimeout(() => { | |
| showToast("Pusher 3D ๋ฌผ๋ฆฌ ์๋ฎฌ๋ ์ดํฐ ์ค๋น ์๋ฃ! ๋ง์ฐ์ค๋ก ํ๊ฒ์ ๋๋๊ทธํด๋ณด์ธ์."); | |
| }, 600); | |
| }); | |